#include "Mesh.h"

using namespace Gut;

void Mesh::Bind()
{
	glBindVertexArray(VAO);
}

void MeshNoIndice::DrawArrays() const
{
	glBindVertexArray(this->VAO);
	glDrawArrays(this->faceType, 0, vertexNum);
	glBindVertexArray(0);
}

bool MeshIndice::CreateFromDesc(const MeshIndiceDesc& desc)
{

	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glGenBuffers(1, &EBO);

	glBindVertexArray(VAO);

	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, desc.vertexStride * desc.vertexNum, desc.vertexheader, desc.usage);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, desc.indiceNum* desc.indiceStride, desc.indiceHeader, desc.usage);


	for(int i=0;i<desc.numLayout;i++)
	{
		const auto& l = desc.layout[i];

		glEnableVertexAttribArray(l.index);

		if (l.type == GL_FLOAT) {
			glVertexAttribPointer(l.index, l.size, l.type, l.normalized,
				desc.vertexStride, (void*)l.offset);
		}
		else if (l.type == GL_INT) {
			glVertexAttribIPointer(l.index, l.size, l.type, desc.vertexStride, (void*)l.offset);
		}
	}

	glBindVertexArray(0);

	this->numIndices = desc.indiceNum;
	this->faceType = desc.face;
	this->indiceStride = desc.indiceStride;

	if (desc.indiceStride == 2)
	{
		this->indiceType = GL_UNSIGNED_SHORT;
	}
	else if (desc.indiceStride == 4)
	{
		this->indiceType = GL_UNSIGNED_INT;
	}
	else if (desc.indiceStride == 1)
	{
		this->indiceType = GL_UNSIGNED_BYTE;
	}
	else
	{
		return false;
	}

	glBindVertexArray(0);

	return true;
}

void MeshIndice::Draw() const
{
	glBindVertexArray(VAO);
	glDrawElements(this->faceType, this->numIndices, this->indiceType, (void*)(this->startIndex * this->indiceStride));
	glBindVertexArray(0);
}

void MeshIndice::DrawInstanced(unsigned int count) const
{
	glBindVertexArray(VAO);
	glDrawElementsInstanced(this->faceType, this->numIndices, this->indiceType, 0, count);
	glBindVertexArray(0);
}

bool MeshNoIndice::CreateFromDesc(const MeshNoIndiceDesc& desc)
{
	bool gr = true;

	unsigned int VBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);

	glBindVertexArray(VAO);

	glBindBuffer(GL_ARRAY_BUFFER, VBO);
	glBufferData(GL_ARRAY_BUFFER, desc.vertexStride * desc.vertexNum, desc.vertexheader, desc.usage);

	for (int i = 0; i < desc.numLayout; i++)
	{
		const auto& l = desc.layout[i];

		glEnableVertexAttribArray(l.index);

		if (l.type == GL_FLOAT) {
			glVertexAttribPointer(l.index, l.size, l.type, l.normalized,
				desc.vertexStride, (void*)l.offset);
		}
		else if (l.type == GL_INT) {
			glVertexAttribIPointer(l.index, l.size, l.type, desc.vertexStride, (void*)l.offset);
		}
	}

	glBindVertexArray(0);

	this->vertexNum = desc.vertexNum;

	return true;
}

